#include "FullState.h"
#include <boost/regex.hpp>

const string FullState::PLAYMODE_REGEX = "\\(pmode ([a-zA-Z_]*)\\)";
string REAL = "(-{0,1}[0-9]+\\.{0,1}[0-9]*)e{0,1}-{0,1}[0-9]*";
const string FullState::BALL_REGEX = "\\(\\(b\\) " + REAL + " " + REAL + " " + REAL + " " + REAL + "\\)";

//nem matcheli a kapust!!
const string FullState::PLAYER_REGEX = "\\(\\(p ([lr]) ([0-9]+) ([0-9]+)\\) " + REAL + " " + REAL + " " + REAL + " " + REAL + " " + REAL + " " + REAL;
const string FullState::TIME_STEP_REGEX = "\\(fullstate ([0-9]+) \\(";


//Kapus es labda!
void FullState::parse(string msg)
{
    int vtimeStep = 0;
    string vplayMode;
    Ball vBall;
    Player vTeams[2][11];
    //vector<Player> vleftTeam;
    //vector<Player> vrighTeam;

    //printf("Try parsing %s\n", msg.c_str());
    regex re;
    cmatch matches;

    re.assign(PLAYMODE_REGEX, boost::regex_constants::icase);

    if (regex_search(msg.c_str(), matches, re))
    {
        string s(matches[1].first, matches[1].second);
        vplayMode = s;

        //printf("Match %s\n", s.c_str());
    }
    else
    {
        printf("Not matched PLAYMODE\n");
    }

    re.assign(BALL_REGEX, boost::regex_constants::icase);

    if (regex_search(msg.c_str(), matches, re))
    {
        string posx(matches[1].first, matches[1].second);
        string posy(matches[2].first, matches[2].second);
        string velx(matches[3].first, matches[3].second);
        string vely(matches[4].first, matches[4].second);

        Vector position(atof(posx.c_str()), atof(posy.c_str()));
        Vector velocity(atof(velx.c_str()), atof(vely.c_str()));

        vBall.setPosition(position);
        vBall.setVelocity(velocity);

        //printf("Match %s\n", s.c_str());
    }
    else
    {
        printf("Not matched BALL\n");
        printf("%s\n", msg.c_str());
    }

    re.assign(TIME_STEP_REGEX, boost::regex_constants::icase);

    if (regex_search(msg.c_str(), matches, re))
    {
        string s(matches[1].first, matches[1].second);

        vtimeStep = atoi(s.c_str());
        //printf("Match %s\n", s.c_str());
    }
    else
    {
        printf("Not matched TIMESTEP\n");
    }


    //loop
    re.assign(PLAYER_REGEX, boost::regex_constants::icase);

    boost::sregex_token_iterator iter(msg.begin(), msg.end(), re, 0);
    boost::sregex_token_iterator end;

    for( ; iter != end; ++iter )
    {
        string s(*iter);
        //printf("%s\n", s.c_str());
       if (regex_search(s.c_str(), matches, re))
       {
           Player player;
           //string s(matches[0].first, matches[0].second);

           string team(matches[1].first, matches[1].second);

           string uNum(matches[2].first, matches[2].second);
           //printf("%s\n", uNum.c_str());
           player.setuNum(atoi(uNum.c_str()));
           string type(matches[3].first, matches[3].second);
           //printf("%s\n", type.c_str());
           //goalie!!
           player.setPlayerType(atoi(type.c_str()));


           string posx(matches[4].first, matches[4].second);
           string posy(matches[5].first, matches[5].second);
           string velx(matches[6].first, matches[6].second);
           string vely(matches[7].first, matches[7].second);

           Vector position(atof(posx.c_str()), atof(posy.c_str()));
           Vector velocity(atof(velx.c_str()), atof(vely.c_str()));

           player.setPosition(position);
           player.setVelocity(velocity);

           string body(matches[8].first, matches[8].second);
           player.setBodyDir(atof(body.c_str()));
           if (!team.compare("l"))
           {
               //printf("Left team\n");
                player.setSide(0);
           }
           else
           {
               //printf("Right team\n");
                player.setSide(1);
           }

           vTeams[player.getSide()][player.getuNum() - 1] = player;

           //printf("Match %s\n", s.c_str());
       }
    }

    /*
    if (regex_search(msg.c_str(), matches, re))
    {
        //string s(matches[0].first, matches[0].second);

        string team(matches[1].first, matches[1].second);

        string uNum(matches[2].first, matches[2].second);
        printf("%s\n", uNum.c_str());
        string type(matches[3].first, matches[3].second);
        printf("%s\n", type.c_str());

        string posx(matches[4].first, matches[4].second);
        string posy(matches[5].first, matches[5].second);
        string velx(matches[6].first, matches[6].second);
        string vely(matches[7].first, matches[7].second);

        Vector position(atof(posx.c_str()), atof(posy.c_str()));
        Vector velocity(atof(velx.c_str()), atof(vely.c_str()));

        //printf("Match %s\n", s.c_str());
    }
    else
    {
        printf("Not matched PLAYER\n");
    }
    */

    mutex.lock();

    playMode = vplayMode;
    ball = vBall;
    timeStep = vtimeStep;

    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 11; ++j)
            teams[i][j] = vTeams[i][j];

    mutex.unlock();
}

FullState & FullState::instance()
{
    static FullState fullstate;
    return fullstate;
}
